#include  "JniMacro.h"

#include <streambuf>
#include <unistd.h>

//不断从FD中读取数据并打印
void *JNIPrivate::pThreadReadStdIO(void *) {
    ssize_t byteCount;
    char buffer[1024];
    while ((byteCount = read(JNIPrivate::fds[0], buffer, sizeof buffer - 1)) > 0) {
        if (buffer[byteCount - 1] == '\n') --byteCount;
        buffer[byteCount] = 0;
        LOGW("%s", buffer);
    }
    return nullptr;
}

//开启JNI日志服务
void JNI::stdioToLogcat() {
    //将stdout与stderror与缓冲区解绑
    setvbuf(stdout, nullptr, _IOFBF, 0);
    setvbuf(stderr, nullptr, _IOFBF, 0);
    //创建FD，并将stdout和stderror连接到FD
    pipe(JNIPrivate::fds); //fds[0]是in，fds[1]是out
    dup2(JNIPrivate::fds[1], 1); //1表示stdout
    dup2(JNIPrivate::fds[1], 2); //2表示stderr
    //开启子线程，不断从File中读取数据并打印
    pthread_create(&JNIPrivate::tid, nullptr, JNIPrivate::pThreadReadStdIO, nullptr);
    pthread_detach(JNIPrivate::tid);
}

//char数组转jstring
//注意，这里的string是一个全局Java变量
//使用完后一定要通过JNI::env->DeleteGlobalRef(string)释放
//由于JVM变量在作用域结束后就会被销毁，因此必须通过引用传入，不能return
void JNI::toJString(const char *charArray, jstring &string) {
    JNIEnv *env = nullptr;
    bool detached = JNI::jvm->GetEnv((void **) &env, JNI_VERSION_1_6) == JNI_EDETACHED;
    if (detached) JNI::jvm->AttachCurrentThread(&env, nullptr);
    jstring localString = env->NewStringUTF(charArray);
    string = (jstring) env->NewGlobalRef(localString);
    if (detached) JNI::jvm->DetachCurrentThread();
}

//jstring转const char*
const char *JNI::toConstChar(jstring jstring) {
    JNIEnv *env = nullptr;
    bool detached = JNI::jvm->GetEnv((void **) &env, JNI_VERSION_1_6) == JNI_EDETACHED;
    if (detached) JNI::jvm->AttachCurrentThread(&env, nullptr);
    const char *charArray = env->GetStringUTFChars(jstring, new jboolean(true));
    if (detached) JNI::jvm->DetachCurrentThread();
    return charArray;
}

//char*转const char*
const char *JNI::toConstChar(char *charArray) {
    return (const char *) charArray;
}

//const char*转char*
char *JNI::toChar(const char *constCharArray) {
    char *charArray = nullptr;
    int length = strlen(constCharArray);
    charArray = new char[length + 1];
    strcpy(charArray, constCharArray);
    return charArray;
}

